package com.itheima.app.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.huanxin.HuanXinTemplate;
import com.itheima.domain.db.Question;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Friend;
import com.itheima.domain.mongo.RecommendUser;
import com.itheima.domain.mongo.UserLocation;
import com.itheima.domain.vo.*;
import com.itheima.service.db.QuestionService;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.*;
import com.itheima.util.ConstantUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class MakeFriendManager {
    @Reference
    private RecommendUserService recommendUserService;

    @Reference
    private UserInfoService userInfoService;

    @Reference
    private VisitorService visitorService;
    @Reference
    private UserLocationService userLocationService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 今日佳人
     * //1.获得当前登录的用户id
     * //2.查询给当前用户推荐的人是谁  RecommendUser
     * //3.RecommendUser有可能为空 构造假数据
     * //4.根据RecommendUser 查询被推荐人的基础信息
     * //5.封装vo对象返回即可
     * @return
     */
    public RecommendUserVo findRecommendUserByUserId() {
        //1.获得当前登录的用户id
        Long loginUserId = UserHolder.getId();
        //2.查询给当前用户推荐的人是谁  RecommendUser
        RecommendUser recommendUser = recommendUserService.findRecommendUserByUserId(loginUserId);
        if(recommendUser == null){
            //3.RecommendUser有可能为空 构造假数据
            recommendUser = new RecommendUser();
            recommendUser.setToUserId( loginUserId );
            recommendUser.setUserId( 1L ); //推荐默认用户
            recommendUser.setScore(99d); //推荐的默认缘分值
        }

        //4.根据RecommendUser 查询被推荐人的基础信息
        UserInfo userInfo = userInfoService.findById(recommendUser.getUserId());

        //5.封装vo对象返回即可
        RecommendUserVo vo = new RecommendUserVo();

        vo.setUserInfo(userInfo);
        vo.setFateValue( recommendUser.getScore().longValue() ); //赋值缘分值
        return vo;
    }

    /**
     * 查询推荐好友
     * //1.获得用户的id
     * //2.调用service进行查询 返回PageBeanVo
     * //3.获得集合对象
     * //4.判断集合是否为空 如果为空 构建假数据
     * //4.判断集合是否为空 如果不为空 遍历数据
     * //5.根据遍历的推荐用户查询 用户的基础信息
     * //6.根据基础信息构建 RecommendUserVo对象
     * //7.返回
     */
    public PageBeanVo findRecommendUser(Integer pageNumber, Integer pageSize) {
        //1.获得用户的id
        Long loginUserId = UserHolder.getId();
        //2.调用service进行查询 返回PageBeanVo
        PageBeanVo pageBeanVo = recommendUserService.findRecommendUser(pageNumber , pageSize ,loginUserId );
        //3.获得集合对象
        List<RecommendUser> items = (List<RecommendUser>) pageBeanVo.getItems();
        //4.判断集合是否为空 如果为空 构建假数据
        if(CollectionUtil.isEmpty(items)){
            items = new ArrayList<>();
            for(int i = 2 ; i <= 12 ; i ++){//推荐十个用户
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setToUserId( loginUserId );
                recommendUser.setUserId( Long.valueOf(i) ); //推荐默认用户
                recommendUser.setScore(RandomUtil.randomDouble(60, 90)); //推荐的默认缘分值
                items.add(recommendUser);
            }
        }
        List<RecommendUserVo> voList = new ArrayList<>();
        //4.判断集合是否为空 如果不为空 遍历数据
        for (RecommendUser recommendUser : items) {
            //5.根据遍历的推荐用户查询 用户的基础信息
            UserInfo userInfo = userInfoService.findById(recommendUser.getUserId());
            //6.根据基础信息构建 RecommendUserVo对象
            RecommendUserVo vo = new RecommendUserVo();
            vo.setUserInfo(userInfo);
            vo.setFateValue( recommendUser.getScore().longValue() );
            voList.add(vo);
        }

        //7.返回
        pageBeanVo.setItems(voList);
        return pageBeanVo;
    }

    /**
     * 查询佳人信息
     * @param recommendUserId
     * @return
     */
    public RecommendUserVo findPersonalInfo(Long recommendUserId) {
        //1.获得当前登录人的id
        Long loginUserId = UserHolder.getId();

        //2.根据loginUserId 和 recommendUserId 查询缘分值
        RecommendUser recommendUser = recommendUserService.findRecommendUser(loginUserId , recommendUserId );

        if(recommendUser == null){//此处判断只是为了不报错.否则 新用户点击推荐用户肯定空指针异常
            recommendUser = new RecommendUser();
            recommendUser.setScore( RandomUtil.randomDouble(60, 90));
        }

        //3.查询用户基础信息
        UserInfo userInfo = userInfoService.findById(recommendUserId);
        //返回
        RecommendUserVo vo = new RecommendUserVo();
        vo.setUserInfo(userInfo);//用户信息
        vo.setFateValue(recommendUser.getScore().longValue());//缘分值
        return vo;
    }

    @Reference
    private QuestionService questionService;
    /**
     * 查询陌生人问题
     * @param userId
     * @return
     */
    public String findStrangerQuestion(Long userId) {
        //1.查询问题对象
        Question question = questionService.findByUserId(userId);

        if(question== null){
            //2.为空
            question = new Question();
            question.setStrangerQuestion("远赴人间惊鸿宴");
        }

        //3.返回
        return question.getStrangerQuestion();
    }

    /**
     * 最近访客
     * //1.获得当前用户的id
     * //2.获得上次登录时间(需要判断是否为空)
     * //3.如果为空 直接返回空集合即可,同时存入一个当前登录的时间
     * //4.如果不为空 根据用户的id查询 和 上一次时间查询访客的列表记录(此处返回值为List<访客id>)
     * //5.根据访客的id 查询UserInfo表获得基础信息
     * //6.将基础信息封装给 VisitorVo
     * //7.更新本次缓存的登录时间
     * @return
     */
    public List<VisitorVo> findVisitor() {
        //1.获得当前用户的id
        Long userId = UserHolder.getId();
        //2.获得上次登录时间(需要判断是否为空)
        String key = ConstantUtil.LAST_ACCESS_TIME + userId;
        String lastTime = stringRedisTemplate.opsForValue().get(key);
        if(StrUtil.isEmpty(lastTime)){//写到注册功能
            //3.如果为空 直接返回空集合即可,同时存入一个当前登录的时间
            stringRedisTemplate.opsForValue().set(key , System.currentTimeMillis() +"");
            return null;
        }
        //4.如果不为空 根据用户的id查询 和 上一次时间查询访客的列表记录(此处返回值为List<访客id>)
        List<Long>  visitorIds =  visitorService.findVisitorIds(userId ,lastTime );
        //创建返回值
        List<VisitorVo> voList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(visitorIds)){
            for (Long visitorId : visitorIds) {
                //5.根据访客的id 查询UserInfo表获得基础信息
                UserInfo userInfo = userInfoService.findById(visitorId);
                //6.将基础信息封装给 VisitorVo
                VisitorVo vo = new VisitorVo();
                //7.查询缘分值
                RecommendUser recommendUser = recommendUserService.findRecommendUser(userId, visitorId);

                vo.setUserInfo(userInfo);
                if(recommendUser == null){//防止没有查询到数据 报错
                    vo.setFateValue(RandomUtil.randomLong(60,90));
                }else{
                    vo.setFateValue(recommendUser.getScore().longValue());
                }
                voList.add(vo);
            }

        }
        //7.更新本次缓存的登录时间
        //TODO 此处有争议  更新缓存的时间 设定
        //stringRedisTemplate.opsForValue().set(key , System.currentTimeMillis() +"");
        return voList;
    }


    /**
     * 上传位置
     * @param latitude
     * @param longitude
     * @param addrStr
     */
    public void saveOrUpdateUserLocation(Double latitude, Double longitude, String addrStr) {
        //保存或者更新位置信息
        userLocationService.saveOrUpdateUserLocation(latitude ,longitude ,  addrStr , UserHolder.getId());
    }

    /**
     * 搜附近
     * @param gender
     * @param distance
     * @return
     */
    public List<NearUserVo> searchUser(String gender, String distance) {
        Long loginUserId = UserHolder.getId();
        //调用方法 查询附件的人
        List<Long> idsList = userLocationService.searchUser( loginUserId,distance );

        List<NearUserVo> voList = new ArrayList<>();
        //判断是否为空
        if(CollectionUtil.isNotEmpty(idsList)){
            for (Long userId : idsList) {
                //根据userId查询UserInfo数据
                UserInfo userInfo = userInfoService.findById(userId);
                if(userInfo.getId() ==loginUserId ){ //排除自己
                    continue;
                }
                if(!StrUtil.equals( gender , userInfo.getGender())){
                    continue;
                }
                //创建vo  封装数据
                NearUserVo vo = new NearUserVo();
                vo.setAvatar(userInfo.getAvatar());
                vo.setNickname(userInfo.getNickname());
                vo.setUserId(userInfo.getId());
                voList.add(vo);
            }
        }
        return voList;
    }


    @Autowired
    private HuanXinTemplate huanXinTemplate;
    /**
     * 打招呼
     * @param questionUserId
     * @param reply
     */
    public void replyStrangerQuestion(String questionUserId, String reply) {
        //1.获得当前用户登录id
        Long loginUserId = UserHolder.getId();
        //2.查询当前用户的昵称
        UserInfo userInfo = userInfoService.findById(loginUserId);
        //3.查询问题
        Question question = questionService.findByUserId(Long.valueOf(questionUserId));

        //4.构建map数据
        Map<String,String> map = new HashMap<>();
        map.put("userId" , loginUserId.toString()); //当前登录用户id
        map.put("nickname" , userInfo.getNickname() ); //当前用户昵称
        if(question == null){
            map.put("strangerQuestion" ,"远赴人间惊鸿宴");//问题
        }else{
            map.put("strangerQuestion" ,question.getStrangerQuestion() );//问题
        }
        map.put("reply" , reply);//回答的内容
        //5.发送消息
        String json = JSON.toJSONString(map); //转换json
        huanXinTemplate.sendMsg( questionUserId , json);
    }

    @Reference
    private FriendService friendService;
    /**
     * 添加联系人
     * @param replyUserId
     */
    public void saveContact(String replyUserId) {
        //1.获得当前登录用户人的id
        Long loginUserId = UserHolder.getId();

        //2.调用service保存mongo中的关系
        friendService.saveContact(loginUserId  , Long.valueOf(replyUserId) );
        //3.保存环信的好友关系
        huanXinTemplate.addContacts(loginUserId ,Long.valueOf(replyUserId) );

    }

    /**
     * 查询用户的好友列表
     * @param pageNumber
     * @param pageSize
     * @return
     */
    public PageBeanVo findContact(Integer pageNumber, Integer pageSize) {
        //1.获得当前用户-> 用户的id
        Long loginUserId = UserHolder.getId();
        //2.调用service 查询好友的列表
        PageBeanVo pageBeanVo = friendService.findContact(pageNumber , pageSize , loginUserId);
        //5.数据转换
        List<Friend> friendList = (List<Friend>) pageBeanVo.getItems();
        List<ContactVo> contactVoList = new ArrayList<>();

        if(CollectionUtil.isNotEmpty(friendList)){
            for (Friend friend : friendList) {
                UserInfo userInfo = userInfoService.findById(friend.getFriendId());//获得用户的信息
                ContactVo contactVo = new ContactVo();//创建封装的对象
                contactVo.setUserInfo(userInfo);
                //contactVo.setId();//数据的表示 没用
                contactVo.setUserId(friend.getFriendId() + "");//好友id
                contactVoList.add(contactVo);//放入集合
            }
        }

        //4.重新封装vo
        pageBeanVo.setItems(contactVoList);

        //3.返回对象
        return pageBeanVo;
    }

    @Reference
    private UserLikeService userLikeService;
    /**
     * 保存用户的喜欢
     * @param userLikeId
     * @return
     */
    public Map saveUserLike(Long userLikeId) {
        //1.获得当前用户id
        Long loginUserId = UserHolder.getId();
        //2.保存用户的喜欢
        userLikeService.saveUserLike(loginUserId , userLikeId);

        //3.调用方法判断用户是否互相喜欢
        boolean flag = userLikeService.isUserLike(loginUserId , userLikeId );

        if(flag){
            //4.true 相互喜欢
            //4.1 加friend好友关系
            friendService.saveContact(loginUserId , userLikeId);
            //4.2 加环信的好友关系
            huanXinTemplate.addContacts(loginUserId , userLikeId);
        }

        return null;
    }

    /**
     * 查看我的喜欢 粉丝 互相喜欢数量
     * @return
     */
    public UserLikeCountVo usersCounts() {
        Long loginUserId = UserHolder.getId();
        //1.查询互相喜欢
        Long eachLoveCount =  userLikeService.findEachLoveCount(loginUserId);
        //2.查询我的喜欢
        Long loveCount =  userLikeService.findLoveCount(loginUserId);
        //3.查询粉丝
        Long fanCount =  userLikeService.findFanCount(loginUserId);
        //4.封装UserLikeCountVo 对象
        UserLikeCountVo vo=  new UserLikeCountVo();
        vo.setEachLoveCount(eachLoveCount);//互相喜欢
        vo.setLoveCount(loveCount);//我的喜欢
        vo.setFanCount(fanCount);//粉丝
        return vo;
    }
}
